package abstractClass;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据访问对象模板 - 抽象类
 */
public abstract class AbstractDaoTemplate<T> {
    
    /**
     * 查询模板方法
     */
    public List<T> executeQuery(String sql, Object... params) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<T> resultList = new ArrayList<>();
        
        try {
            // 1. 获取数据库连接
            conn = getConnection();
            
            // 2. 创建预处理语句
            pstmt = conn.prepareStatement(sql);
            
            // 3. 设置参数
            setParameters(pstmt, params);
            
            // 4. 执行查询
            rs = pstmt.executeQuery();
            
            // 5. 处理结果集
            while (rs.next()) {
                T entity = rowMapper(rs);
                resultList.add(entity);
            }
            
        } catch (SQLException e) {
            handleException(e);
        } finally {
            // 6. 释放资源
            closeResources(conn, pstmt, rs);
        }
        
        return resultList;
    }
    
    /**
     * 更新模板方法
     */
    public int executeUpdate(String sql, Object... params) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        int affectedRows = 0;
        
        try {
            // 1. 获取数据库连接
            conn = getConnection();
            
            // 2. 创建预处理语句
            pstmt = conn.prepareStatement(sql);
            
            // 3. 设置参数
            setParameters(pstmt, params);
            
            // 4. 执行更新
            affectedRows = pstmt.executeUpdate();
            
        } catch (SQLException e) {
            handleException(e);
        } finally {
            // 5. 释放资源
            closeResources(conn, pstmt, null);
        }
        
        return affectedRows;
    }
    
    // 抽象方法 - 必须由子类实现
    
    /**
     * 获取数据库连接
     */
    protected abstract Connection getConnection() throws SQLException;
    
    /**
     * 结果集映射 - 将ResultSet转换为实体对象
     */
    protected abstract T rowMapper(ResultSet rs) throws SQLException;
    
    // 具体方法 - 提供默认实现
    
    /**
     * 设置SQL参数
     */
    protected void setParameters(PreparedStatement pstmt, Object... params) 
            throws SQLException {
        if (params != null) {
            for (int i = 0; i < params.length; i++) {
                pstmt.setObject(i + 1, params[i]);
            }
        }
    }
    
    /**
     * 异常处理
     */
    protected void handleException(SQLException e) {
        System.err.println("数据库操作异常: " + e.getMessage());
        e.printStackTrace();
    }
    
    /**
     * 释放资源
     */
    protected void closeResources(Connection conn, PreparedStatement pstmt, ResultSet rs) {
        try {
            if (rs != null) rs.close();
            if (pstmt != null) pstmt.close();
            if (conn != null) conn.close();
        } catch (SQLException e) {
            System.err.println("资源释放异常: " + e.getMessage());
        }
    }
}